#include "stdafx.h"
#include "TestAppRunNotification.h"


CTestAppRunNotification::CTestAppRunNotification(void) :
m_pITestRunNotification(NULL)
{
}

CTestAppRunNotification::~CTestAppRunNotification(void)
{
	Dispose();
}

void CTestAppRunNotification::Init(ITestRunNotification * pITestRunNotification)
{
	Reset();

	m_pITestRunNotification = pITestRunNotification;
}

void CTestAppRunNotification::Reset()
{
	m_wsz[0] = L'\0';
	m_hEvent.Close();
	m_hMmf.Close();
}

void CTestAppRunNotification::Dispose()
{
	Reset();
	m_pITestRunNotification = NULL;
}

void CTestAppRunNotification::TestAppNotify(WPARAM wParam, LPARAM lParam)
{
	ATLASSERT(m_pITestRunNotification); //The class initialization MUST be done
	if (m_pITestRunNotification == NULL)
		return;
	
	switch((ETestRunExchangeStep)wParam)
	{
	case stepStartNotification:
		StartNotification((DWORD)lParam);
		break;
	case stepTestSet:
		TestSet((DWORD)lParam);
		break;
	case stepGroupStartNotification:
		GroupStartNotification((DWORD)lParam);
		break;
	case stepTestStartNotification:
		TestStartNotification((DWORD)lParam);
		break;
	case stepTestEndNotification:
		TestEndNotification((DWORD)lParam);
		break;
	case stepGroupEndNotification:
		GroupEndNotification((DWORD)lParam);
		break;
	case stepEndNotification:
		EndNotification();
		break;
	default:
		Abort();
		break;
	}

}

void CTestAppRunNotification::Abort()
{
	Reset();

	m_pITestRunNotification->AbortNotification();
}

void CTestAppRunNotification::StartNotification(DWORD dwTestAppProcessId)
{
	Reset();

	wchar_t wsz[40];
	swprintf_s(wsz, _countof(wsz), L"cputaddin_%i", GetCurrentProcessId());
	m_hEvent.Attach(OpenEvent(EVENT_MODIFY_STATE, FALSE, wsz));
	
	if (m_hEvent.m_h)
	{
		swprintf_s(m_wsz, _countof(m_wsz), L"%s_%i", wsz, dwTestAppProcessId);
		m_pITestRunNotification->StartNotification(dwTestAppProcessId);

		SetEvent(m_hEvent);
	}
	else
	{
		Abort();
	}
}

void CTestAppRunNotification::TestSet(DWORD nSize)
{
	if (m_hEvent.m_h == NULL)
	{
		Abort();
		return;
	}

	m_hMmf.Attach(OpenFileMappingW(FILE_MAP_WRITE | FILE_MAP_READ, FALSE, m_wsz));
	if (m_hMmf.m_h == NULL)
	{
		Abort();
	} else
	{
		LPVOID lp = MapViewOfFile(m_hMmf, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, nSize);
		if (lp)
		{
			TestPackTransData csTestSet;
			csTestSet.DeSerialize((LPBYTE)lp, (DWORD)nSize);
		
			m_pITestRunNotification->TestSet(csTestSet);

			ATLASSERT(csTestSet.DefineSize() != nSize);
			csTestSet.Serialize((LPBYTE)lp, (DWORD)nSize);

			UnmapViewOfFile(lp);
		}
		else
		{
			Abort();
		}
	}

	SetEvent(m_hEvent);
}

void CTestAppRunNotification::GroupStartNotification(DWORD nSize)
{
	if ((m_hEvent.m_h == NULL) || (m_hMmf.m_h == NULL) || (nSize != 4))
	{
		Abort();
		return;
	}

	LPVOID lp = MapViewOfFile(m_hMmf, FILE_MAP_READ, 0, 0, 4);
	if (lp)
	{
		DWORD nGroupParam = *((LPDWORD)lp);
		m_pITestRunNotification->GroupStartNotification(nGroupParam);
		UnmapViewOfFile(lp);
	} 
	else
	{
		Abort();
	}

	SetEvent(m_hEvent);
}

void CTestAppRunNotification::TestStartNotification(DWORD nSize)
{
	if ((m_hEvent.m_h == NULL) || (m_hMmf.m_h == NULL) || (nSize != 8))
	{
		Abort();
		return;
	}

	LPVOID lp = MapViewOfFile(m_hMmf, FILE_MAP_READ, 0, 0, 8);
	if (lp)
	{
		LPDWORD pDw = (LPDWORD)lp;
		DWORD nGroupParam = *pDw; ++pDw;
		DWORD nTestParam = *pDw;
		m_pITestRunNotification->TestStartNotification(nGroupParam, nTestParam);
		UnmapViewOfFile(lp);
	} 
	else
	{
		Abort();
	}

	SetEvent(m_hEvent);
}

void CTestAppRunNotification::TestEndNotification(DWORD nSize)
{
	if ((m_hEvent.m_h == NULL) || (m_hMmf.m_h == NULL))
	{
		Abort();
		return;
	}

	LPVOID lp = MapViewOfFile(m_hMmf, FILE_MAP_READ, 0, 0, nSize);
	if (lp)
	{
		LPDWORD pDw = (LPDWORD)lp;
		DWORD nGroupParam = *pDw; ++pDw;
		DWORD nTestParam = *pDw; ++pDw;
		ERunStatus eRunStatus = (ERunStatus)*pDw; ++pDw;
		__time64_t tDuration = *((__time64_t*)pDw); ++pDw; ++pDw;
		DWORD dwLen = *pDw; ++pDw;
		LPCWSTR lpReport = (LPCWSTR)pDw;

		m_pITestRunNotification->TestEndNotification(nGroupParam, nTestParam, eRunStatus, tDuration, lpReport);
		UnmapViewOfFile(lp);
	} 
	else
	{
		Abort();
	}

	SetEvent(m_hEvent);
}

void CTestAppRunNotification::GroupEndNotification(DWORD nSize)
{
	if ((m_hEvent.m_h == NULL) || (m_hMmf.m_h == NULL))
	{
		Abort();
		return;
	}
	
	LPVOID lp = MapViewOfFile(m_hMmf, FILE_MAP_READ, 0, 0, nSize);
	if (lp)
	{
		LPDWORD pDw = (LPDWORD)lp;
		DWORD nGroupParam = *pDw; ++pDw;
		ERunStatus eRunStatus = (ERunStatus)*pDw; ++pDw;
		__time64_t tDuration = *((__time64_t*)pDw); ++pDw; ++pDw;
		DWORD dwLen = *pDw; ++pDw;
		LPCWSTR lpReport = (LPCWSTR)pDw;

		m_pITestRunNotification->GroupEndNotification(nGroupParam, eRunStatus, tDuration, lpReport);
		UnmapViewOfFile(lp);
	} 
	else
	{
		Abort();
	}

	SetEvent(m_hEvent);
}

void CTestAppRunNotification::EndNotification()
{
	if (m_hEvent.m_h == NULL)
	{
		Abort();
		return;
	}

	SetEvent(m_hEvent);

	Reset();
	m_pITestRunNotification->EndNotification();
}